bitkeeper revision 1.1062.2.1 (40f14d93VNnMM_iUKi37Qk5Dj84vwA)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Sun, 11 Jul 2004 14:24:19 +0000 (14:24 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Sun, 11 Jul 2004 14:24:19 +0000 (14:24 +0000)
More x86-64 fixes. We now boot to C code.

xen/arch/x86/boot/x86_64.S
xen/include/asm-x86/msr.h
xen/include/xen/multiboot.h

index ab5219f64c2e0643613eacc95a455cc858cd1e03..a765141910f44d9d5d964ae4de36918f346791e4 100644 (file)
@@ -1,10 +1,11 @@
 #include <xen/config.h>
 #include <hypervisor-ifs/hypervisor-if.h>
 #include <asm/page.h>
+#include <asm/msr.h>
 
 #define  SECONDARY_CPU_FLAG 0xA5A5A5A5
                 
-               .text
+        .text
         .code32
         
 ENTRY(start)
@@ -13,11 +14,11 @@ ENTRY(start)
         .org    0x004
 /*** MULTIBOOT HEADER ****/
         /* Magic number indicating a Multiboot header. */
-       .long   0x1BADB002
-       /* Flags to bootloader (see Multiboot spec). */
-       .long   0x00000002
-       /* Checksum: must be the negated sum of the first two fields. */
-       .long   -0x1BADB004
+        .long   0x1BADB002
+        /* Flags to bootloader (see Multiboot spec). */
+        .long   0x00000002
+        /* Checksum: must be the negated sum of the first two fields. */
+        .long   -0x1BADB004
 
         .org    0x010
         .asciz "Bad CPU: does not support 64-bit (long) mode."
@@ -66,38 +67,30 @@ __start:
         mov     $0x20,%ecx # X86_CR4_PAE
         mov     %ecx,%cr4
 
-        cmp     $(SECONDARY_CPU_FLAG),%ebx
-        je      start_paging
-
         mov     %ebx,0x1001e0 /* Multiboot info struct */
         mov     %eax,0x1001e4 /* Multiboot magic value */
 
-        /* Initialize mappings of 1GB of memory. */
-        mov     $0x103000,%edi               /* idle_pg_table_l2 */
-        mov     $0x1e3,%eax                  /* PRESENT+RW+A+D+PSE+GLOBAL */
-        mov     $512,%ecx
-1:      stosl
-        add     $0x200000,%eax
-        loop    1b
-
-start_paging:
+        /* Load pagetable base register. */
         mov     $0x101000,%eax   /* idle_pg_table */
         mov     %eax,%cr3
+
+        /* Set up EFER (Extended Feature Enable Register). */
+        movl    $MSR_EFER, %ecx
+        rdmsr
+        /* Long Mode, SYSCALL/SYSRET, No-Execute */
+        movl    $(EFER_LME|EFER_SCE|EFER_NX),%eax
+        wrmsr
+
         mov     $0x80050033,%eax /* hi-to-lo: PG,AM,WP,NE,ET,MP,PE */
         mov     %eax,%cr0
         jmp     1f
-1:      /* Now in compatibility mode. Long-jump into 64-bit mode. */
-        ljmp    $(__HYPERVISOR_CS64),$0x1000e0
 
+1:      /* Now in compatibility mode. Long-jump into 64-bit mode. */
+        ljmp    $(__HYPERVISOR_CS64),$0x100100
+        
         .code64
-        .org    0x00e0
+        .org    0x0100
 
-        /* Jump to high mappings. */
-        mov     high_start(%rip),%rax
-        push    %rax
-        ret
-__high_start:
-        
         /* Install relocated selectors (FS/GS unused). */
         lgdt    gdt_descr(%rip)
         mov     $(__HYPERVISOR_DS),%ecx
@@ -112,9 +105,15 @@ __high_start:
         mov     stack_start(%rip),%rsp
         
         /* Reset EFLAGS (subsumes CLI and CLD). */
-       pushq   $0
-       popf
+        pushq   $0
+        popf
 
+        /* Jump to high mappings. */
+        mov     high_start(%rip),%rax
+        push    %rax
+        ret
+__high_start:
+        
         lidt    idt_descr(%rip)
                 
         cmp     $(SECONDARY_CPU_FLAG),%ebx
@@ -139,19 +138,15 @@ __high_start:
         add     $8,%rdi
         loop    1b
 
-        xor     %rax,%rax
         mov     0x1001e0,%eax /* Multiboot info struct */
         lea     start(%rip),%rbx
         sub     $0x100000,%rbx
         add     %rbx,%rax
         push    %rax
-        xor     %rax,%rax
         mov     0x1001e4,%eax /* Multiboot magic value */
         push    %rax
         
-        /* Call into main C routine. This should never return.*/
-               call    cmain
-        ud2     /* Force a panic (invalid opcode). */
+        call    cmain
 
 /* This is the default interrupt handler. */
 int_msg:
@@ -167,7 +162,9 @@ ignore_int:
 1:      jmp     1b
 
         .code32
-                
+
+        .org    0x1e0
+                        
 /*** DESCRIPTOR TABLES ***/
 
 .globl SYMBOL_NAME(idt)
@@ -192,35 +189,51 @@ ENTRY(gdt_table)
 
         .word   0
 gdt_descr:
-       .word   (LAST_RESERVED_GDT_ENTRY*8)+7
+        .word   (LAST_RESERVED_GDT_ENTRY*8)+7
 SYMBOL_NAME(gdt):       
         .quad   SYMBOL_NAME(gdt_table)
 
         .word   0    
 idt_descr:
-       .word   256*8-1
+        .word   256*8-1
 SYMBOL_NAME(idt):
-        .quad  SYMBOL_NAME(idt_table)
+        .quad   SYMBOL_NAME(idt_table)
 
 ENTRY(stack_start)
-        .quad   SYMBOL_NAME(cpu0_stack) + 8100 - __PAGE_OFFSET
+        .quad   SYMBOL_NAME(cpu0_stack) + 8100
 
 high_start:
         .quad   __high_start
                 
+/* Initial PML4 -- level-4 page table */
         .org 0x1000
 ENTRY(idle_pg_table)
 ENTRY(idle_pg_table_4)
         .quad 0x0000000000102007 # PML4[0]
         .fill 261,8,0
         .quad 0x0000000000102007 # PML4[262]
+
+/* Initial PDP -- level-3 page table */
         .org 0x2000
 ENTRY(idle_pg_table_l3)
         .quad 0x0000000000103007
+
+/* Initial PDE -- level-2 page table. */
         .org 0x3000
 ENTRY(idle_pg_table_l2)
+        .macro identmap from=0, count=512
+        .if \count-1
+        identmap "(\from+0)","(\count/2)"
+        identmap "(\from+(0x200000*(\count/2)))","(\count/2)"
+        .else
+        .quad 0x00000000000001e3 + \from
+        .endif
+        .endm
+        identmap /* Too orangey for crows :-) */
+
         .org 0x4000
 ENTRY(cpu0_stack)    # Initial stack is 8kB
+
         .org 0x6000
 ENTRY(stext)
 ENTRY(_stext)
index b66ccd2ff7e9517c3c5a323fe7687d43a85238b2..a412963fd9920314391fe2db26c40764aebf0172 100644 (file)
@@ -71,8 +71,8 @@
 #define _EFER_NX 11  /* No execute enable */
 
 #define EFER_SCE (1<<_EFER_SCE)
-#define EFER_LME (1<<EFER_LME)
-#define EFER_LMA (1<<EFER_LMA)
+#define EFER_LME (1<<_EFER_LME)
+#define EFER_LMA (1<<_EFER_LMA)
 #define EFER_NX (1<<_EFER_NX)
 
 /* Intel MSRs. Some also available on other CPUs */
index 4a68f31a0bc5b765d7e0f85317c5f9db997c2900..037a59cf7452016ca1d8673bc868f807ed94332d 100644 (file)
 #ifndef __MULTIBOOT_H__
 #define __MULTIBOOT_H__
 
-#ifndef __ELF__
-#error "Build on a 32-bit ELF system"
-#endif
-
 /* The magic number passed by a Multiboot-compliant boot loader. */
-#define MULTIBOOT_BOOTLOADER_MAGIC     0x2BADB002
+#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
 
 /* The symbol table for a.out.  */
-typedef struct
-{
-  unsigned long tabsize;
-  unsigned long strsize;
-  unsigned long addr;
-  unsigned long reserved;
+typedef struct {
+    u32 tabsize;
+    u32 strsize;
+    u32 addr;
+    u32 reserved;
 } aout_symbol_table_t;
 
 /* The section header table for ELF.  */
-typedef struct
-{
-  unsigned long num;
-  unsigned long size;
-  unsigned long addr;
-  unsigned long shndx;
+typedef struct {
+    u32 num;
+    u32 size;
+    u32 addr;
+    u32 shndx;
 } elf_section_header_table_t;
 
 /* The Multiboot information.  */
-typedef struct
-{
-  unsigned long flags;
-  unsigned long mem_lower;
-  unsigned long mem_upper;
-  unsigned long boot_device;
-  unsigned long cmdline;
-  unsigned long mods_count;
-  unsigned long mods_addr;
-  union
-  {
-    aout_symbol_table_t aout_sym;
-    elf_section_header_table_t elf_sec;
-  } u;
-  unsigned long mmap_length;
-  unsigned long mmap_addr;
+typedef struct {
+    u32 flags;
+    u32 mem_lower;
+    u32 mem_upper;
+    u32 boot_device;
+    u32 cmdline;
+    u32 mods_count;
+    u32 mods_addr;
+    union {
+        aout_symbol_table_t aout_sym;
+        elf_section_header_table_t elf_sec;
+    } u;
+    u32 mmap_length;
+    u32 mmap_addr;
 } multiboot_info_t;
 
 /* The module structure.  */
-typedef struct
-{
-  unsigned long mod_start;
-  unsigned long mod_end;
-  unsigned long string;
-  unsigned long reserved;
+typedef struct {
+    u32 mod_start;
+    u32 mod_end;
+    u32 string;
+    u32 reserved;
 } module_t;
 
 /* The memory map. Be careful that the offset 0 is base_addr_low
    but no size.  */
-typedef struct
-{
-  unsigned long size;
-  unsigned long base_addr_low;
-  unsigned long base_addr_high;
-  unsigned long length_low;
-  unsigned long length_high;
-  unsigned long type;
+typedef struct {
+    u32 size;
+    u32 base_addr_low;
+    u32 base_addr_high;
+    u32 length_low;
+    u32 length_high;
+    u32 type;
 } memory_map_t;
 
 #endif /* __MULTIBOOT_H__ */